perm filename A83.TEX[106,RWF] blob
sn#827494 filedate 1986-10-31 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 \magnification\magstephalf
C00011 ENDMK
C⊗;
\magnification\magstephalf
\input macro.tex
\def\today{\ifcase\month\or
January\or February\or March\or April\or May\or June\or
July\or August\or September\or October\or November\or December\fi
\space\number\day, \number\year}
\baselineskip 14pt
\rm
\parskip 6pt
\line{\sevenrm a83.tex[106,phy] \today\hfill}
\bigskip
\noindent{\bf Aliasing.}
Sometimes distinct internal names correspond to identical external names.
If the law says the mayor must be out of the room while the corporate counsel
makes his report to the board of supervisors,
and Manny Hatz is both mayor and corporate counsel, there
is a problem. The problem arose because the lawmakers did not envision the
possibility, which arises when using internal names, that different names
might identify the same person. Multiple names for the same person or entry
are called {\sl aliases\/}, and use of aliases to get special or unwanted
effects is called {\sl aliasing\/}.
Parameters are internal names. Value parameters are separate, unique objects,
not aliases;
they get their values from the (external) corresponding arguments, but
changing a value parameter has no effect on the argument. Variable
parameters, though, are simply internal names for the corresponding
arguments, so an argument may be referred to within a procedure both
by an
external name (as a global variable) and by one or more internal names
(as a variable parameter). Designing a procedure without imagining the
possibility of aliasing is inviting ants to the picnic.
For example, we want a procedure which multiplies complex number~$x$
by complex number~$y$, leaving its result in~$z$. Since Pascal does not
have complex variables, we would represent each parameter by separate
real and imaginary parts; a~procedure which works in the
absence of aliasing is
\medskip
{\obeylines\obeyspaces\let =\ \tt\baselineskip12pt
PROCEDURE COMPLEXMULT(VAR XREAL,XIMAG,YREAL,YIMAG,ZREAL,ZIMAG: REAL);
BEGIN
ZREAL:=XREAL*YREAL-XIMAG*YIMAG;
ZIMAG:=XREAL*YIMAG+YREAL*XIMAG
END;
}
\medskip\noindent
If the call is {\tt COMPLEXMULT(AR,AI,BR,BI,AR,AI)}, though, both {\tt ZREAL}
and {\tt XREAL} are aliases for~{\tt AR}, and {\tt AR} is changed by the
assignment to {\tt ZREAL} before being used (as {\tt XREAL}) by the
assignment to {\tt ZIMAG}. As a result, the procedure does not have the
desired effect of {\tt A:=A*B}.
Ordinarily, it is a mistake for a procedure to assign a value to a variable
and then use that value through an alias, or assign another value to the same
variable through an alias. In the complex multiply example, the first
error can be avoided by letting the inputs be value parameters:
\medskip
{\obeylines\obeyspaces\let =\ \tt
PROCEDURE COMPLEXMULT(XREAL,XIMAG,YREAL,YIMAG: REAL; VAR ZREAL,ZIMAG: REAL);
}
\medskip\noindent
while avoiding the second error requires that the last two arguments not be
equal (or themselves aliases).
Aliasing may occur among external files as well as among procedure arguments.
It is usually an error for distinct internal file names to have the same
external name.
{\narrower\smallskip\noindent
{\bf Rule of Good Programming Practice:}
If a parameter provides input only, consider making it a value parameter.
Check that no aliasing occurs among arguments of variable parameters,
including appearances as global variables in the procedure body.
\smallskip}
{\rmn
{\narrower\smallskip\noindent
{\bf Exercise:} (Arrays as parameters.) [assumes aliasing]
\noindent
Let the integer array {\tt P[0:20]} represent the polynomial
$P[0]+P[1]x+P[2]x↑2+\cdots +P[20]x↑{20}=
\sum↓{i=0}↑{20}P[i]x↑i$. Write and test a procedure headed
{\obeylines\obeyspaces\let =\ \tt
POLYMULT(VAR P,Q,R:POLY)
}
\noindent
which, treating {\tt P} and~{\tt Q} as polynomials, multiplies them, leaving
the product in~{\tt R}. Use this procedure to raise $x↑2-x-1$ to the tenth power.
Define the type {\tt POLY} as {\tt ARRAY[0..20] OF INTEGER}.
\smallskip
\noindent{\bf Solution.}
%\smallskip
%
%{\obeylines\obeyspaces\let =\ \tt
% $\vdots$
% BEGIN
% FOR I:=0 TO 20 DO R[I]:=0;
%
% FOR I:=0 TO 20 DO
% FOR J:=0 TO 20-I DO
% R[I+J]:=R[I+J]+P[I]*Q[J]
% END
%}
\smallskip
{\obeylines\obeyspaces\let =\ \tt
POLYMULT(P,Q: POLY; VAR R: POLY);
VAR T: POLY; I,J: INTEGER;
BEGIN
FOR I:=0 TO 20 DO T[I]:=0;
FOR I:=0 TO 20 DO
FOR J:=0 TO 20-I DO
T[I+J]:=T[I+J]+P[I]*Q[J];
FOR I:=0 TO 20 DO
R[I]:=T[I]
END;
}
\smallskip
\noindent Caution: if the product is computed directly in~{\tt R},
instead of being computed in~{\tt T} and then moved to~{\tt R}
as above, the algorithm will fail on calls like {\tt POLYMULT(X,Y,X)}
because of aliasing.
\smallskip}
}
\bigskip
\parindent0pt
\copyright 1984 Robert W. Floyd
First draft July 19, 1984
\bye
\bigskip
\line{\copyright 1985 Robert W. Floyd\hfill}
\line{First draft (not published) April 8, l985.\hfill}
\bye